// VuePress内置函数
/* const {
  logger,
  fs,
  path
} = require('@vuepress/shared-utils') */
const path = require("path");
const fs = require("fs");

/* const url = require('url'); */

// 实现深拷贝
const _ = require('lodash');
// 默认插件配置
const defaultPluginConfig = require('./default_plugin_config');
// 文件操作封装工具类
const fileUtil = require('./fileUtil');
// 自定义控制台打印函数
const helper_live2d_log = require('./helper_live2d_log');

// 自定义插件实现
module.exports = (options = {}, context) => ({
  /* 插件的名称 */
  name: defaultPluginConfig.pluginName,

  /* 在应用初始化之后，并在某些特定的函数式 API 执行之前执行 */
  async ready() {
    // Object.assign函数为浅拷贝 | lodash为深拷贝
    options = _.defaultsDeep({}, options, defaultPluginConfig);
    const {
      siteConfig = {}, // 站点配置
        outDir, // 输出目录
        sourceDir // 文档的根目录路径
    } = context
    // 获取主题插件的配置
    const live2dConfig = options.live2d || (siteConfig.themeConfig.yilia_plus ?
      siteConfig.themeConfig.yilia_plus.live2d : {})
    // 合并默认配置和插件配置
    options.live2d = _.defaultsDeep({}, live2dConfig, defaultPluginConfig.live2d);

    // 进行删除文件夹(查找需要删除的文件夹名称之后才进行删除，不建议全删除整个文件夹)
    const delDirPath = path.join((sourceDir || options.dest), options.outDir, options.outDirName);
    const delFolders = fileUtil.listFolder(path.resolve(__dirname, path.join('./public/live2d')));
    if (!!delFolders) {
      for (let folder of delFolders) {
        // 模型文件夹名称
        let modelDirName = path.basename(folder);
        if (options.live2d && options.live2d.enable && modelDirName == options.live2d.model) {
          // 正在使用的则跳过删除
          options.log && helper_live2d_log(`跳过删除--- ${options.live2d.model}`);
          continue;
        }
        // 待删除的模型文件夹
        let modelDirPath = path.join(delDirPath, modelDirName);
        if (fs.existsSync(modelDirPath)) {
          fileUtil.deleteFolder(modelDirPath);
          options.log && helper_live2d_log(`清理文件夹资源--- ${modelDirPath}`);
        }
      }
    }

    if (options.live2d && options.live2d.enable) {
      options.log && helper_live2d_log("Generating live2d...");
      // `__dirname` 指向当前被执行js文件的所在目录绝对路径
      // path.join(__dirname,'./public/live2d')
      const modelFiles = fileUtil.listFiles(path.resolve(__dirname, path.join('./public/live2d',
        options.live2d.model, options.live2d.pluginModelPath)));
      if (!!modelFiles) {
        // modelFiles.map((file) => 
        for (const file of modelFiles) {
          // helper_live2d_log(file)
          // 将绝对路径转为相对路径(基于当前工作目录)
          const tempOutFilePath = path.relative(path.resolve(__dirname, path.join('./public/live2d')), file);
          // For windows style path, we replace '\' to '/'.
          // tempOutFilePath = tempOutFilePath.replace(/(\\|\/)+/g, '/');
          // 拼接输出路径
          const distPath = path.join((sourceDir || options.dest), options.outDir, options.outDirName, tempOutFilePath);

          if (!fs.existsSync(distPath)) {
            helper_live2d_log("开始生成文件：" + tempOutFilePath);
            // 递归创建目录(path.dirname函数返回路径中代表文件夹的部分)
            createListDirSync(path.dirname(distPath));
            // fs.writeFile读取二进制文件有误
            // await fs.writeFile(
            //   distPath,
            //   await fs.readFile(file, 'utf8'), {}
            // )
            // fs流读取写入
            const writeStream = fs.createWriteStream(distPath);
            await fs.createReadStream(file, {
              flags: 'r'
              // encoding: 'utf8'
            }).pipe(writeStream);
            writeStream.on('error', (error) => {
              helper_live2d_log('writeStream error' + error.message);
            });

          } else {
            // 文件已存在，暂时不操作
            // helper_live2d_log('文件已存在，暂时不操作');
          }
        }
      } else {
        helper_live2d_log("配置项错误,请检查配置...", "red");
      }
    }

    // 临时文件所在的根目录路径
    // helper_live2d_log(context.tempPath);
    // 自定义临时常量
    const name = "JoeyBling.txt",
      gitRepoUrl = "https://github.com/JoeyBling/vuepress-theme-yilia-plus",
      content = "",
      dirName = 'author';
    /* 一个用于向 tempPath 写入临时文件的方法。 */
    await context.writeTemp && context.writeTemp(
      `${dirName}/${name}`,
      `
/**
* Generated by "${options.pluginName}"
* @author ${gitRepoUrl}
*/
${content}\n\n`.trim())

  },

  define() {
    if (options.log) {
      helper_live2d_log("加载插件配置：" + (JSON.stringify ? JSON.stringify(options.live2d) : options.live2d));
    }
    return {
      // LIVE2D_CONFIG: JSON.stringify(options.live2d)
      OPTIONS: JSON.stringify(options)
    };
  },

  /* 指向增强文件的绝对文件路径或返回该路径的函数 */
  enhanceAppFiles: [
    path.resolve(__dirname, './lib/enhanceAppFile.js')
  ],
  /* 指向 mixin 文件的路径，它让你可以控制根组件的生命周期 */
  clientRootMixin: path.resolve(__dirname, './lib/clientRootMixin.js'),

  /* 拓展或者修改 $page 对象。这个函数将会在编译器为每个页面执行一次 */
  extendPageData($page) {
    if ($page._content && !!$page._content.length) {
      /* 可以在任意的 Vue 中通过 this.$page.size 来访问这个变量 */
      $page.size = ($page._content.length / 1024).toFixed(2) + 'kb';
    } else {
      // console.log($page);
    }
  },

  /* 全局 UI Vue 组件 */
  globalUIComponents: ['Live2D'],

  /* 在生产环境的构建结束后被调用，生成的页面的路径数组将作为该函数的第一个参数 */
  async generated() {
    const {
      pages,
      locales,
      base
    } = context.getSiteData ?
      context.getSiteData() :
      context;
  }
});

/**
 * 递归创建目录
 * @param {文件夹路径} dir 
 */
const createListDirSync = function (dir) {
  // 以同步的方法检测目录是否存在
  if (fs.existsSync(dir)) {
    return;
  }

  try {
    fs.mkdirSync(dir, 0777);
    helper_live2d_log("递归创建文件夹：" + dir);
  } catch (err) {
    if (err.code == 'ENOENT') {
      //create parent dir(返回路径中代表文件夹的部分)
      createListDirSync(path.dirname(dir))
      //create dir
      createListDirSync(dir)
    }
  }
};
